<?
class gravy extends errorHandler{
	
	//The Encryption Object.
	public $encryptor=null;
	
	//The Database.
	public $db;
	
	//The Validation Class.
	public $validator;
	
	//The Messages Holder.
	public $messages;

	public function __construct(){
		parent::__construct();

		#Create the database object.
		$this->db=new database($this);

		#Create the Encryption Object.
		$this->encryptor=new encryption();

		#Set the page to the default page title, for the moment.
		$this->validator=new validator();

		#Set the page to the default page title, for the moment.
		$this->messages=array();
	}

	/*
	** RC4 Encryption Wrapper Function.
	**  This is a wrapper for the $this->encrypt->rc4encrypt() function.
	**  @return string.
	*/
	public function encrypt($value=NULL){
		if(strlen($this->config->SALT)>0){
			$value=$this->config->SALT.$value;
		}
		#$this->debug("enc",$value);
		return($this->encryptor->rc4encrypt($value,$this->config->RC4_KEY));
	}

	/*
	** RC4 Decryption Wrapper Function.
	**  This is a wrapper for the $this->encrypt->rc4decrypt() function.
	**  @return string.
	*/
	public function decrypt($value=NULL){
		$result=$this->encryptor->rc4decrypt($value,$this->config->RC4_KEY);
		if(strlen($this->config->SALT)>0){
			$result=substr($result,strlen($this->config->SALT));
		}
		#$this->debug("decry",$result);
		return($result);
	}

	/*
	** Session Variables Function.
	**  This function Get and Sets Session Variabled. If VALUE isn't supplied it gets the variable.
	**  @return string.
	*/
	public function session($key="",$value=NULL){
		$result=0;

		if(strlen($key)>0){
			if($this->config->USE_ENCRYPTION){
				$key=$this->encrypt($key);
			}

			if($value!==NULL){

				// serialize to support object and array data
				$value=serialize($value);

				if($this->config->USE_ENCRYPTION){
					$_SESSION[$key]=$this->encrypt($value);
				}else{
					$_SESSION[$key]=$value;
				}
			}
			if($this->config->USE_ENCRYPTION){
				$result=unserialize($this->decrypt($_SESSION[$key]));
			}else{
				$result=unserialize($_SESSION[$key]);
			}
		}else{
			$result=array();
			foreach($_SESSION as $key=>$value){
				if($this->config->USE_ENCRYPTION){
					$result[$this->decrypt($key)]=unserialize($this->decrypt($value));
				}else{
					$result[$key]=unserialize($value);
				}
			}
		}
		if($result===NULL){
			#$this->debug("Session result is equal to null");
			$result="";
		}
		return($result);
	}

	/*
	** Clear the Session.
	**  @return void.
	*/
	public function clear_session(){
		session_destroy();
	}

	/*
	** Session Field
	**  @return result.
	*/
	public function sessionField($reset,$sessionVar,&$rv){
		if($reset){
			$this->session($sessionVar,$rv);
		}else{
			$rv=$this->session($sessionVar);
		}
	}

	/*
	** Cookie Function.
	**  This function Get and Sets Cookies. If VALUE isn't supplied it gets the variable.
	**  @return string.
	*/
	public function cookie($key="",$value=NULL,$expires=NULL,$path=NULL,$domain=NULL){
		$result=0;
		$raw_key=$key;
		$raw_value=$value;
		if(strlen($key)>0){
			if($this->config->USE_ENCRYPTION){
				$key=$this->encrypt($key);
			}
			if($value!==NULL){
				if($this->config->USE_ENCRYPTION){
					$cookieValue=$this->encrypt($value);
				}else{
					$cookieValue=$value;
				}
				if($expires===NULL){
					//Default to 30 days in the future.
					$expires=time()+(60*60*24*30);
				}
				if(!@setcookie($key,$cookieValue,$expires,WEB_ROOT)){
					$this->addError($this->HEADERS_ALREADY_SENT,"gravy.cookie.set.headersAlreadySent",array("key"=>$raw_key,"value"=>$raw_value,"expires"=>$expires),false);
				}
			}
			if($this->config->USE_ENCRYPTION){
				$result=$this->decrypt(@$_COOKIE[$key]);
			}else{
				$result=$_COOKIE[$key];
			}
		}else{
			$result=array();
			foreach($_COOKIE as $key=>$value){
				if($this->config->USE_ENCRYPTION){
					$result[$this->decrypt($key)]=$this->decrypt($value);
				}else{
					$result[$key]=$value;
				}
			}
		}
		if($result===NULL){
			$result="";
		}
		return($result);
	}

	/*
	** Sanitation Routine.
	**  This function removes anything from a string that is not in the alphabet.
	**  @return string.
	*/
	public function sanitize($str=""){
		return(ereg_replace("[^A-Za-z]","",$str));
	}

	/*
	** Connect to the Database.
	**  This function connects to the database.
	**  @return bool.
	*/
	public function dbConnect($connection=NULL){
		$result=false;
		$connection=($connection===NULL)?"default":$connection;
		$dbConfig=$this->config->database[$connection];
		if(strtolower($dbConfig["interface"])=="mssql"){
		}elseif($this->db->connect($dbConfig["database"],$dbConfig["user"],$dbConfig["password"],$dbConfig["host"])){
			#$this->debug("Database Connected ($connection).",$dbConfig);
			$result=true;
		}else{
			$this->debug("Couldnt connect to the database ($connection).",$dbConfig);
		}
		return($result);
	}

	/*
	** Close a connection to the Database.
	**  This function closes a connection to the database.
	**  @return bool.
	*/
	public function dbClose(){
		return($this->db->close());
	}

	/*
	** Merges an objects errors with this ones.
	**  @return bool.
	*/
	public function mergeErrors($obj){
		if($obj instanceof errorHandler){
			if(count($obj->errors)>0){
				$obj->isError=true;
				$this->isError=true;
			}
			if($obj->isError){
				$this->errors=array_merge($this->errors,$obj->errors);
			}
		}
	}


	public function redirect($url){
		header("location:$url");
		exit();
	}
	
	/*
	** Cleans up session variables and other things that need cleaning.
	**  @return void.
	*/
	public function cleanUp(){
	}
	
	/*
	** Gets the URL of the current page, while allowing modifications to the parameters to the QueryString.
	**  @return String.
	*/
	public function getUrl($full=true,$qsVals=NULL,$noQs=false,$altUrl=NULL){
		$result=($altUrl===NULL)?$_SERVER['REQUEST_URI']:$altUrl;
		if($full){
			#$pathinfo=pathinfo();
			#$result=$pathinfo["http"]."://".$pathinfo["hostname"].$pathinfo["path"];
			#if(strlen($pathinfo["query"])>0){
			#	$result.="?".$pathinfo["query"];
			#}
			#$result.=$pathinfo["fragment"];
		}
		if(is_string($qsVals)){
//			$ar=split("&",$qsVals);
			$ar=preg_split("/&/",$qsVals);
			$qsVals=array();
			for($c=0;$c<count($ar);$c++){
//				$tmp=split("=",$ar[$c]);
				$tmp=preg_split("/=/",$ar[$c]);
				if(count($tmp)==2){
					$qsVals[$tmp[0]]=$tmp[1];
				}else{
					$qsVals[$tmp[0]]="";
				}
			}
		}
		if(is_array($qsVals)){
			$keys=array_keys($qsVals);
			for($c=0;$c<count($keys);$c++){
				$key=$keys[$c];
				$value=$qsVals[$key];
				$result=preg_replace("/".$key."=[^&]*/","",$result);
				$result=preg_replace("/&{1,}/","&",$result);
				if(substr_count($result,"?")<1){
					$result.="?";
				}
				if(substr($result,-1)=="?"||substr($result,-1)=="&"){
					$result.="$key=$value";
				}else{
					$result.="&$key=$value";
				}
			}
		}
		if($noQs){
//			$result=split("\?",$result);
			$result=preg_split("/\?/",$result);
			$result=$result[0];
		}
		return($result);
	}

	public function ajaxUrl($var=NULL,$default=false){
		$result=false;

		$fullUrl=parse_url(self::getUrl());
		$this->debug("fullUrl",$fullUrl);
		$hash=$fullUrl["fragment"];
		$hash=preg_split("/&amp;/",$hash);
		$params=array();

		if(is_array($hash)&&count($hash)>0){
			for($c=0;$c<count($hash);$c++){
				$pair=preg_split("/=/",$hash[$c]);
				if(is_array($pair)&&count($pair)>1){
					$params[$pair[0]]=$pair[1];
				}else{
					$params[$pair[0]]=$default;
				}
			}
		}
		if($var===NULL){
			if($params){
				$result=$params;
			}else{
				$result=$default;
			}
		}else{
			if(array_has_key($params,$var)){
				$result=$params[$var];
			}else{
				$result=$default;
			}
		}
		return($result);
	}

	/*
	** Make a nice URL out of the provided string.
	**  @return String.
	*/
	public function makeNiceUrl($str=NULL){
		return(self::niceUrl($str));
	}

	/*
	** Make a nice URL out of the provided string.
	**  @return String.
	*/
	static public function niceUrl($str=NULL){
		$result=$str;
		$result=preg_replace("/\s/","-",$result);
		$result=preg_replace("/&amp;/","&",$result);
		$result=preg_replace("/&/","and",$result);
		$result=preg_replace("/[^a-zA-Z0-9_\-]/","",$result);
		$result=preg_replace("/\-{2,}/","-",$result);
		return($result);
	}
	
	/*
	** Get current page title
	**  @return String.
	*/
	public function getPageTitle($title=false) {
	    return false;
	}
	
	/*
	** Get/Set Global Variable
	*/
	public function globals($key=NULL,$val=NULL){
		$result=false;
		if($key!==NULL&&$val!==NULL){
			$GLOBALS[$key]=$val;
		}
		if($key!==NULL){
			$result=$GLOBALS[$key];
		}
		if($key===NULL&&$val===NULL){
			$result=$GLOBALS;
		}
		return($result);
	}

	/*
	** Add query string items on to a URL.
	**  @return String.
	*/
	public function addToQueryString($url="",$ar=NULL){
		$result=$url;
		if(strpos($result,"?")>-1){
			$result.="&";
		}else{
			$result.="?";
		}
		if(is_array($ar)){
			foreach($ar as $key=>$value){
				$result.="$key=$value&";
			}
		}
		$result=substr($result,0,-1);
		return($result);
	}
	
	/*
	** Save message for the user.
	**  @return void.
	*/
	public function addMessage($message=NULL,$title=NULL,$severity=NULL){
		$severity=($severity===NULL)?errorHandler::SEVERITY_OK:$severity;
		$title=($title===NULL)?"":$title;
		if(!array_key_exists($severity,$this->messages)){
			$this->messages[$severity]=array();
		}
		if(!array_key_exists($title,$this->messages[$severity])){
			$this->messages[$severity][$title]=array();
		}
		$this->messages[$severity][$title][]=$message;
	}
	
	/*
	** Write out a HTML Comment.
	**  @return void.
	*/
	public function htmlComment($comment=NULL){
		print("<!-- ".$comment." //-->".chr(13));
	}
	
	/*
	** Output saved messages to the user.
	**  @return void.
	*/
	public function outputMessages(){
		if(count($this->messages)>0){
			foreach($this->messages as $severity=>$titles){
				$message="";
				foreach($titles as $title=>$messages){
					if(strlen($title)>0){
						$message.="<h1>$title</h1>";
					}
					if(count($messages)>0){
						$message.="<ol>";
						for($c=0;$c<count($messages);$c++){
							$message.="<li>".$messages[$c]."</li>";
						}
						$message.="</ol>";
					}
				}
				if(strlen($message)>0){
					print('<div id="gravyMessage" class="gravyMessage gravy-'.$severity.'">'.$message.'</div>');
				}
			}
		}
	}

	/*
	** Random String Generation.
	**  @return string.
	*/
	public function rndstr($len=6,$chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"){
		$result="";
		for($c=1;$c<=$len;$c++){
			$result.=substr($chars,rand(0,strlen($chars)-1),1);
		}
		return($result);
	}

	/*
	** Get the Full Url of the current page.
	**  @return string.
	*/
	public function getFullUrl(){
		return($this->logger->getFullUrl());
	}
}
?>